@tool
class_name AbilityManager
extends Node2D

#region 属性
#endregion
#region 字段
var cur_ability:int = (int)(pow(2,32) - 1) & ~GameEnum.EntityAbility.Nothing:
	set(value):
		var temp_value = value
		if cur_ability & GameEnum.EntityAbility.Nothing == 0 and value & GameEnum.EntityAbility.Nothing > 0:
			temp_value = GameEnum.EntityAbility.Nothing
		elif cur_ability & GameEnum.EntityAbility.Everything == 0 and value & GameEnum.EntityAbility.Everything > 0:
			temp_value = (int)(pow(2,32) - 1) & ~GameEnum.EntityAbility.Nothing
		elif cur_ability & GameEnum.EntityAbility.Nothing > 0 and value != GameEnum.EntityAbility.Nothing:
			temp_value = value & ~GameEnum.EntityAbility.Nothing
		elif cur_ability & GameEnum.EntityAbility.Everything > 0 and value != (int)(pow(2,32) - 1) & ~GameEnum.EntityAbility.Nothing:
			temp_value = value & ~GameEnum.EntityAbility.Everything
		cur_ability = temp_value
#endregion
#region 信号
signal on_cur_ability_changed(cur_ability:int,changed_ability:GameEnum.EntityAbility)
#endregion

#region 基类方法
#endregion
#region 公共方法
func is_ability_valid(ability:GameEnum.EntityAbility)->bool:
	return cur_ability & ability > 0
func get_valid_ability()->GameEnum.EntityAbility:
	return cur_ability
func get_invalid_ability()->GameEnum.EntityAbility:
	return ~cur_ability
func set_ability(ability:GameEnum.EntityAbility,isValid:bool)->GameEnum.EntityAbility:
	var changed_ability:GameEnum.EntityAbility = cur_ability
	if isValid:
		cur_ability |= ability
	else:
		cur_ability &= ~ability
	changed_ability ^= cur_ability
	on_cur_ability_changed.emit(cur_ability,changed_ability)
	return changed_ability
#endregion
#region 私有方法
func _get_one_count(num):
	var count = 0
	while num > 0:
		if num & 1 > 0:
			count += 1
		num >>= 1
	return count
func _get_hint_string() -> String:
	var arr = []
	for key in GameEnum.EntityAbility.keys():
		## 去掉方便操作的Ability复合类型
		if _get_one_count(GameEnum.EntityAbility[key]) == 1:
			arr.append(key)
	return ",".join(arr)
#endregion
#region 生命周期函数
func _get_property_list():
	var properties = []

	properties.append({
		"name" = "cur_ability",
		"type" = TYPE_INT,
		"usage" = PROPERTY_USAGE_DEFAULT,
		"hint" = PROPERTY_HINT_FLAGS,
		"hint_string" = _get_hint_string(),
	})
	return properties
#endregion
